﻿//-----------------------------------------------------------------------
// <copyright file="Create.cs" company="Microsoft">
// Copyright (c) Microsoft Corporation.  All rights reserved.
// THIS CODE AND INFORMATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY 
// KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
// PARTICULAR PURPOSE.
// </copyright>
// <author>Mark Phillips</author>
// <email>andyr</email>
// <date>2004-03-23</date>
// <summary>Allows creation and modification of an SMTP server.</summary>
//-----------------------------------------------------------------------

namespace Microsoft.Sdc.Tasks.Web.Smtp
{
    using System;
    using System.Xml;
    using System.Globalization;
    using System.Net;
    using Microsoft.Sdc.Tasks.Configuration.Web;
    using Microsoft.Build.Framework;

    /// <summary>
    /// Create a new SMTP Server.
    /// </summary>
    /// <remarks>
    /// <code><![CDATA[<Web.Smtp.Create
    ///     Description="description"
    ///     IPAddress="ipAddress"
    ///     Port="port"
    ///     AuthFlags="authflags" 
    ///     SmartHost="smartHost"
    ///     MasqueradeDomain="masqueradeDomain"
    ///     FullyQualifiedDomainName="fullyQualifiedDomainName"
    ///        DefaultDomain="defaultDomain"
    ///     PickupDirectory="pickupDirectory"
    ///        DropDirectory="dropDirectory"
    ///        QueueDirectory="queueDirectory"
    ///        BadMailDirectory="badMailDirectory"
    ///     Identifier="identifier"
    ///     HostName="hostName"  />]]></code>
    /// <para>where:</para>
    /// <para><i>description (Required)</i></para>
    /// <para>A description for the SMTP site to be created.</para>
    /// <para><i>ipAddress</i></para>
    /// <para>IP address to listen on. This can be any valid IPV4 address. 
    /// If this IP address is not bound to a local NIC the SMTP server will not start.
    /// If this property is not set, the SMTP site will listen on all available 
    /// addresses on the hosting machine.</para>
    /// <para><i>port</i></para>
    /// <para>Port for the FTP site to listen on.</para>
    /// <para><i>authFlags</i></para>
    /// <para>Authentication flags for the SMTP site (either "Anonymous", "Basic", "NTLM", or "Digest")</para>
    /// <para><i>identifier</i></para>
    /// <para>Any non-existant FTP site identifier.</para>
    /// <para><i>hostName</i></para>
    /// <para>Host header to bind to (only valid for non-SSL sites).</para>
    /// <para><i>smartHost</i></para>
    /// <para>The smarthost to forward messages to.</para>
    /// <para><i>masqueradeDomain</i></para>
    /// <para>The masquerade domain to use.</para>
    /// <para><i>fullyQualifiedDomainName</i></para>
    /// <para>The FQDN to use.</para>
    /// <para><i>defaultDomain</i></para>
    /// <para>The default domain to use.</para>
    /// <para><i>pickupDirectory</i></para>
    /// <para>The folder for the pickup directory.</para>
    /// <para><i>dropDirectory</i></para>
    /// <para>The folder for the drop directory.</para>
    /// <para><i>queueDirectory</i></para>
    /// <para>The folder for the queue directory.</para>
    /// <para><i>badMailDirectory</i></para>
    /// <para>The folder for the bad mail directory.</para>
    /// </remarks>
    /// <example>
    /// <code><![CDATA[
    /// <Project>
    ///     <Target Name="Test" >
    ///         <Web.Smtp.Create
    ///             Description="TestSmtp"
    ///             DropDirectory="c:\smtp\drop"
    ///                PickupDirectory="c:\smtp\pickup"
    ///                QueueDirectory="c:\smtp\queue"
    ///                BadMailDirectory="c:\smtp\badmail"
    ///             SmartHost="MySmartHost"
    ///                DefaultDomain="MyDefaultDomain"
    ///             AuthFlags="Anonymous"
    ///            />
    ///     </Target>
    /// </Project>
    /// ]]></code>    
    /// </example>    
    public class Create : TaskBase
    {
        private string description;
        private string ipAddress;
        private string port;
        private string hostName;
        private string smartHost;
        private string defaultDomain;
        private string masqueradeDomain;
        private string fullyQualifiedDomainName;
        private string dropDirectory;
        private string pickupDirectory;
        private string queueDirectory;
        private string badMailDirectory;
        private string identifier;
        private string authFlagsFromConfig;
        private bool force = false;
        private AuthFlags authFlags = 0;
        private Microsoft.Sdc.Tasks.Configuration.Web.SmtpService smtp = null;

        /// <summary>
        /// Initializes a new instance of the Create class.
        /// </summary>
        public Create()
        {
        }

        /// <summary>
        /// Performs the action of this task.
        /// </summary>
        protected override void InternalExecute()
        {
            #region Execute code

            if (authFlagsFromConfig == null || authFlagsFromConfig.Length == 0)
            {
                authFlags = Microsoft.Sdc.Tasks.Configuration.Web.AuthFlags.Anonymous;
            }
            else
            {
                string[] authFlagsSplit = authFlagsFromConfig.Split(' ');
                foreach (string authFlagsSplitItem in authFlagsSplit)
                {
                    object flags = Enum.Parse(typeof(AuthFlags), authFlagsSplitItem, true);
                    authFlags = authFlags | (AuthFlags)flags;
                }
            }

            if (Microsoft.Sdc.Tasks.Configuration.Web.SmtpService.Exists(description))
            {
                Log.LogMessage(MessageImportance.Low, String.Format("Smtp server {0} exists.", description));

                if (force == false)
                {
                    throw new TaskException("Web.Smtp.NoForce");
                }
                else
                {
                    smtp = SmtpService.Load(description);
                }
            }
            else
            {
                Log.LogMessage(MessageImportance.Low, String.Format("Smtp server {0} does not exist so it will be created.", description));
                if (smtp != null)
                {
                    smtp = new Microsoft.Sdc.Tasks.Configuration.Web.SmtpService();
                }
            }

                if (description == null || description.Length == 0)
                {
                    throw new TaskException("Web.DescriptionNotSpecified");
                }

                if (port == null || port.Length == 0)
                {
                    port = "21";
                }

                smtp.Description = description;
                smtp.Port = Convert.ToInt32(port, CultureInfo.InvariantCulture);
                smtp.RootAuthFlags = authFlags;

                if (this.dropDirectory != null && this.dropDirectory.Length > 0)
                {
                    smtp.DropDirectory = this.dropDirectory;
                }

                if (this.pickupDirectory != null && this.pickupDirectory.Length > 0)
                {
                    smtp.PickupDirectory = this.pickupDirectory;
                }

                if (this.queueDirectory != null && this.queueDirectory.Length > 0)
                {
                    smtp.QueueDirectory = this.queueDirectory;
                }

                if (this.badMailDirectory != null && this.badMailDirectory.Length > 0)
                {
                    smtp.BadMailDirectory = this.badMailDirectory;
                }

                if (this.defaultDomain != null && this.defaultDomain.Length > 0)
                {
                    smtp.DefaultDomain = this.defaultDomain;
                }

                if (this.fullyQualifiedDomainName != null && this.fullyQualifiedDomainName.Length > 0)
                {
                    smtp.FullyQualifiedDomainName = this.fullyQualifiedDomainName;
                }

                if (this.smartHost != null && this.smartHost.Length > 0)
                {
                    smtp.SmartHost = this.smartHost;
                }

                if (ipAddress != null && ipAddress.Length > 0)
                {
                    smtp.IPAddress = System.Net.IPAddress.Parse(ipAddress);
                }
                if (identifier != null && identifier.Length > 0)
                {
                    smtp.Identifier = Convert.ToInt32(identifier, CultureInfo.InvariantCulture);
                }
                if (hostName != null && hostName.Length > 0)
                {
                    smtp.HostName = hostName;
                }
                smtp.Save();

            #endregion
        }


        /// <summary>
        /// FTP site description
        /// </summary>
        /// <value>Any valid description for the SMTP server</value>
        [Required]
        public string Description
        {
            get
            {
                return (description == null ? String.Empty : description);
            }
            set
            {
                description = value;
            }
        }

        /// <summary>
        /// IP address to listen on
        /// </summary>
        /// <value>Any valid IPV4 address. 
        /// If this IP address is not bound to a local
        /// NIC the SMTP server will not start.
        /// If this property is not set the ftp site will listen on all available 
        /// addresses on the hosting machine</value>
        public string IPAddress
        {
            get
            {
                return (ipAddress == null ? String.Empty : ipAddress);
            }
            set
            {
                ipAddress = value;
            }
        }

        /// <summary>
        /// Port for the SMTP site to listen on
        /// </summary>
        /// <value>A valid port number.</value>
        public string Port
        {
            get
            {
                return (port == null ? String.Empty : port);
            }
            set
            {
                port = value;
            }
        }


        /// <summary>
        /// SMTP site identifier
        /// </summary>
        /// <value>Any non-existant smtp site identifier</value>
        public string Identifier
        {
            get
            {
                return (identifier == null ? String.Empty : identifier);
            }
            set
            {
                identifier = value;
            }
        }

        /// <summary>
        /// Auth flags for the SMTP site
        /// </summary>
        /// <value>Can be:
        /// "Anonymous"
        /// "Build"
        /// "NTLM"
        /// "Digest"
        /// These 4 values may be combined.</value>
        public string AuthFlags
        {
            get
            {
                return (authFlagsFromConfig == null ? String.Empty : authFlagsFromConfig);
            }
            set
            {
                authFlagsFromConfig = value;
            }
        }

        /// <summary>
        /// Host header to bind to (only valid for non-SSL sites).
        /// </summary>
        /// <value>Host header to bind to (only valid for non-SSL sites).</value>
        public string HostName
        {
            get
            {
                return (hostName == null ? String.Empty : hostName);
            }
            set
            {
                hostName = value;
            }
        }

        public string SmartHost
        {
            get
            {
                return (smartHost == null ? String.Empty : smartHost);
            }
            set
            {
                smartHost = value;
            }
        }

        public string MasqueradeDomain
        {
            get
            {
                return (masqueradeDomain == null ? String.Empty : masqueradeDomain);
            }
            set
            {
                masqueradeDomain = value;
            }
        }

        public string DefaultDomain
        {
            get
            {
                return (DefaultDomain == null ? String.Empty : defaultDomain);
            }
            set
            {
                defaultDomain = value;
            }
        }

        public string FullyQualifiedDomainName
        {
            get
            {
                return (fullyQualifiedDomainName == null ? String.Empty : fullyQualifiedDomainName);
            }
            set
            {
                fullyQualifiedDomainName = value;
            }
        }

        public string DropDirectory
        {
            get
            {
                return (dropDirectory == null ? String.Empty : dropDirectory);
            }
            set
            {
                dropDirectory = value;
            }
        }

        public string PickupDirectory
        {
            get
            {
                return (pickupDirectory == null ? String.Empty : pickupDirectory);
            }
            set
            {
                pickupDirectory = value;
            }
        }

        public string QueueDirectory
        {
            get
            {
                return (queueDirectory == null ? String.Empty : queueDirectory);
            }
            set
            {
                queueDirectory = value;
            }
        }

        public string BadMailDirectory
        {
            get
            {
                return (badMailDirectory == null ? String.Empty : badMailDirectory);
            }
            set
            {
                badMailDirectory = value;
            }
        }

        public bool Force
        {
            get
            {
                return force;
            }
            set
            {
                force = value;
            }
        }
    }
}